/**
 * 公式的http请求对象
 * */

import axios from 'axios';
import qs from 'qs';
import apiList from './api';
import Sign from './sign';
import store from '../../store';
import {Toast} from 'mint-ui';
import config from '@/config/config';

// axios 配置
const axiosConfig = {
  baseURL: config.api_url,
  timeout: 50000,
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
};

// 加/解密对象
const sign = {
  // 解密
  decode: e => {
    return Sign.decode_post(e);
  },
  // 加密
  encode: e => {
    Sign.params = e;
    return Sign.encode_post();
  }
};

// 加载中弹出层
const load = {
  // 打开弹出层
  open: () => {
    // 开启loading
    Vue.$indicator.open({
      text: '加载中...',
      spinnerType: 'snake'
    });
    // console.log('open');
  },
  // 关闭弹出层
  close: (isAll = false) => {
    Vue.$indicator.close();
    if (isAll) {
      // console.log('close all');
    } else { 
      // console.log('close');
    }
  },
};

function initData(data) {
  let out = Object.assign({}, data);
  Object.keys(out).map(k => {
    if (!out[k] && out[k] !== 0) delete out[k];
  });
  return out;
}

function initConfig(config) {
  let out = Object.assign({
    isSign: false, // 是否需要加密
    loading: true, // 是否显示loading
    needXToken: true, // 是否需要xToken
    resDataKey: 'data', // 返回数据内容的key
  }, axiosConfig, config);

  out.headers = Object.assign({
    ...axiosConfig.headers
  }, out.headers);
  out.headers['x-token'] = out.needXToken ? store.getters.xToken : '';

  return out;
}

// 是否正确返回
function isSuccessRes(res) {
  return res.code * 1 === config.ERR_OK;
}

class Index {

  http(url = '', data = {}, config = {}, method = 'post') {
    let params = initData(data);
    config = initConfig(config);
    let {isSign, loading, resDataKey} = config;
    delete config.isSign;
    delete config.loading;
    delete config.resDataKey;
    delete config.needXToken;
    isSign && (params = JSON.parse(sign.encode(params)));
    loading && load.open();
    params = qs.stringify(params);
    return axios[method](url, params, config).then(res => {
      let result = isSign ? sign.decode(res.data) : res.data;
       // 关闭loading
      load.close();
      if (isSuccessRes(result)) {
        return resDataKey ? result[resDataKey] : result;
      } else {
        throw result;
      }
    });
  }

  post(url, data, config) {
    return this.http(url, data, config, 'post');
  }

  get(url, data, config) {
    return this.http(url, data, config, 'get');
  }

  test(...arg) {
    let [url, data, config, method] = arg;
    let configs = initConfig(Object.assign({...config}, {
      loading: false,
      resDataKey: '',
    }));
    let out = {};
    method = method || 'post';
    console.log(url, ':data:>', data);
    console.log(url, ':initData:>', initData(data));
    console.log(url, ':config:>', config);
    console.log(url, ':initConfig:>', initConfig({...config}));
    this.http(url, data, configs, method).then(res => {
      console.log(url, ':res:>', res);
      Object.assign(out, res);
      if (!Object.keys(out).length) out.status = true;
    }).catch(err => {
      Object.assign(out, err);
      if (!Object.keys(out).length) out.status = false;
      console.log(url, ':error:>', err);
    });
    return out;
  }

  $post(url, data, config) {
    config = config || {};
    config.isSign = true;
    return this.post(url, data, config);
  }

  download(url, params = {}, config = {}) {
    Object.keys(params).map(e => {
      // 去掉空的参数
      if (!params[e] && params[e] !== 0) {
        delete params[e];
      }
    });
    let data = params;
    if (config.isSign) {
      data = JSON.parse(sign.encode(params));
    }
    if (config.needXToken) {
      data['X-token'] = store.getters.xToken;
    }
    let pathData = [];
    Object.keys(data).map(k => {
      pathData.push(`${k}=${data[k]}`);
    });
    let api = /^https?/.test(url) ? '' : api_url;
    return api + url + '?' + pathData.join('&');
  }

  $err(err) {
    // 错误处理
    load.close(true);
    console.log(err);
    if(err.code){
      Toast(err.msg);
    }else{
      Toast('网络错误！');
    }
  }

}

let http = new Index();
Object.assign(http, apiList);
export default http;